
module mbox.Types ;

public import
	
	tango.core.Array,
	tango.core.Atomic,
	tango.core.Memory,
	tango.core.Thread,
	tango.core.sync.Mutex,
	tango.core.sync.Semaphore,

	tango.io.device.Array,
	tango.io.device.File,
        tango.io.stream.Lines,
	tango.io.Console,
	tango.io.Stdout,

	Pth	= tango.io.Path ,

	tango.net.InternetAddress,
	tango.net.device.Berkeley,
	tango.net.device.Socket,
	tango.net.device.SSLSocket,

	Txt	= tango.text.Util ,
	Int	= tango.text.convert.Integer,
	Utf	= tango.text.convert.Utf ,
	TimS	= tango.text.convert.TimeStamp,
	
 	tango.sys.Common,
	tango.sys.win32.UserGdi,

	tango.time.Clock,
	tango.time.Time,
	
	B64	= tango.util.encode.Base64,

	sqlite3d.all,

	mbox.Conf,
	mbox.Db ,
	mbox.Dns ,
	mbox.Reader ,
	mbox.Sender ;
	
extern(C) {
	void exit(int) ;
}

extern(Windows){
	const MAX_SCOPE_ID_LEN		= 256 ;
	struct IP_ADDRESS_STRING {
		char[4 * 4]	String ;
	}
	alias IP_ADDRESS_STRING IP_MASK_STRING;
	alias IP_ADDRESS_STRING* PIP_MASK_STRING, PIP_ADDRESS_STRING;

	struct IP_ADDR_STRING {
		IP_ADDR_STRING*	Next;
		IP_ADDRESS_STRING	IpAddress;
		IP_MASK_STRING		IpMask;
		DWORD			Context;
	}
	alias IP_ADDR_STRING* PIP_ADDR_STRING;
	enum {
		BROADCAST_NODETYPE	= 0x0001 ,
		PEER_TO_PEER_NODETYPE	= 0x0002 ,
		MIXED_NODETYPE		= 0x0004 ,
		HYBRID_NODETYPE		= 0x0008 ,
	}
	const MAX_HOSTNAME_LEN		= 128;
	const MAX_DOMAIN_NAME_LEN	= 128;
	
	struct FIXED_INFO {
		char[MAX_HOSTNAME_LEN + 4]		HostName;
		char[MAX_DOMAIN_NAME_LEN + 4]	DomainName;
		PIP_ADDR_STRING				CurrentDnsServer;
		IP_ADDR_STRING					DnsServerList;
		UINT							NodeType;
		char[MAX_SCOPE_ID_LEN + 4]		ScopeId;
		UINT							EnableRouting;
		UINT							EnableProxy;
		UINT							EnableDns;
	}
	alias FIXED_INFO* PFIXED_INFO;

	DWORD GetNetworkParams(PFIXED_INFO, PULONG);
}

struct LineSocket {
	Socket		_soc ;
	Lines!(char)	_it ;
	
        void write(void[] buf)  {
                _soc.write(buf);
        }
	
        int read(void[] buf)  {
               return	_soc.read(buf) ;
        }
	
	void close(){
		_soc.close ;
	}
	
        char[] get()  {
                char[] to_return; 
                _it.readln(to_return); 
		version(DEV){
			Stdout.formatln("get: `{}`",  to_return ).flush ;
		}
                return to_return; 
        }
	
        void put(void[] buf) {
		version(DEV){
			Stdout.formatln("put: `{}`", cast(char[]) buf ).flush ;
		}
		_soc.write(buf);
		_soc.write("\r\n");
        }
	
	
	static LineSocket* Init(Socket soc) {
		LineSocket* p	= new LineSocket;
		p._soc		= soc ;
		p._it			=  new Lines!(char)(p._soc); 
		return p ;
	}
}